//===============================================================================
// Microsoft patterns & practices
// Guidance Explorer Offline Client
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================



using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

using GuidanceExplorer.Services;

namespace GuidanceExplorer.Model
{
    public class FullTextCriteria : Criteria
    {
        /// <summary>
        /// The text that will be searched.
        /// </summary>
        private string _text;

        /// <summary>
        /// The guidance model reference.
        /// </summary>
        private Guidance _guidance;

        /// <summary>
        /// The RegularExpression used to evaluate the Guidance Items
        /// </summary>
        Regex _regEx;

        /// <summary>
        /// Creates a new full text search.
        /// </summary>
        /// <param name="text"></param>
        public FullTextCriteria(Guidance guidance, string text)
        {
            _guidance = guidance;
            _text = text;
            MakeRegularExpression();
        }

        /// <summary>
        /// Evaluate the criteria in the item.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public override bool Evaluate(GuidanceItem item)
        {
            GuidanceItemFileReference gifr = item as GuidanceItemFileReference;
            if (null == gifr)
            {
                gifr = _guidance.GetGuidanceItemFileReference(item);
            }

            if (null == gifr)
            {
                return false;
            }

            if (null != gifr.Title &&
                _regEx.Match(gifr.Title).Success)
            {
                return true;
            }

            foreach (KeyValuePair<String, String> pair in gifr.CustomData)
            {
                if (null != pair.Value && _regEx.Match(pair.Value).Success)
                {
                    return true;
                }
            }

            HtmlRenderService html = new HtmlRenderService();
            String content = html.GetDocumentText(gifr);

            if (null != content && _regEx.Match(content).Success)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// The text that will be searched.
        /// </summary>
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }

        /// <summary>
        /// Creates the regular expression
        /// </summary>
        private void MakeRegularExpression()
        {
            StringBuilder regExpressionPattern = new StringBuilder("(");
            string pattern = (string)_text.Clone();
            string[] phrases = pattern.Trim().Split(new string[] { "\"" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string val in phrases)
            {
                //This condition is used to filter de first and last segments that are included in the split
                if (pattern.Contains("\"" + val + "\""))
                {
                    regExpressionPattern.Append("(" + val + ")(.*?)");
                    pattern = pattern.Replace("\"" + val + "\"", string.Empty);
                }
            }

            string[] searchValues = pattern.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (phrases.Length > 0 && searchValues.Length == 0)
            {
                regExpressionPattern.Remove(regExpressionPattern.Length - 5, 5);
            }

            foreach (string val in searchValues)
            {
                regExpressionPattern.Append(val + "(.*?)");
            }

            if (searchValues.Length > 0)
            {
                regExpressionPattern.Remove(regExpressionPattern.Length - 5, 5);
            }
            regExpressionPattern.Append(")");
            _regEx = new Regex(regExpressionPattern.ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled);
        }
    }
}

